<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Steering Behaviours: EVADE</title>
    <link rel="stylesheet" type="text/css" href="css/main.css" />
    <script src="../libs/dat.gui.min.js"></script>
    <script src="../libs/stats.min.js"></script>
    <script src="../libs/three.min.js"></script>
    <script src="../js/threejs/controls/OrbitControls.js"></script>
    <script src="../js/ThreeSteer.js"></script>
    <link rel="stylesheet" type="text/css" href="css/gui.css" />
  </head>
  <script>
    var container;
    var camera;

    var scene, renderer;
    var controls;
    var stats;
    var entity1, entity2;
    var boundaries;
    var params;

    function onClick(event) {
      if (event.altKey) {
        var mouse3D = new THREE.Vector3(
          (event.clientX / window.innerWidth) * 2 - 1,
          -(event.clientY / window.innerHeight) * 2 + 1,
          0
        );
        var raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(mouse3D, camera);
        var intersects = raycaster.intersectObjects(scene.children);
        if (intersects.length > 0) {
          entity1.position.set(
            intersects[0].point.x,
            intersects[0].point.y,
            intersects[0].point.z
          );
        }
      }
    }

    function init(element) {
      container = document.getElementById(element);
      camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / window.innerHeight,
        1,
        50000
      );
      scene = new THREE.Scene();

      renderer = new THREE.WebGLRenderer({ alpha: true });
      renderer.setClearColor(0x333333, 0);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.domElement.style.position = "absolute";
      renderer.domElement.style.top = 0;
      container.appendChild(renderer.domElement);

      camera.position.set(0, 10000, 10000);
      camera.lookAt(new THREE.Vector3(0, 0, 0));

      controls = new THREE.OrbitControls(camera, renderer.domElement);
      controls.maxPolarAngle = Math.PI * 0.5;
      controls.minDistance = 100;
      controls.maxDistance = 30000;

      stats = new Stats();
      stats.domElement.style.position = "absolute";
      stats.domElement.style.bottom = "0px";
      stats.domElement.style.left = "180px";
      stats.domElement.style.zIndex = 100;
      container.appendChild(stats.domElement);

      // Floor
      var floorGeometry = new THREE.PlaneGeometry(10000, 10000, 32);
      var floorMaterial = new THREE.MeshBasicMaterial({
        color: 0x666666,
        transparent: true,
        opacity: 0.5,
      });
      var floor = new THREE.Mesh(floorGeometry, floorMaterial);
      floor.rotation.x = -Math.PI * 0.5;
      scene.add(floor);

      // Entity Mesh
      var geometry = new THREE.BoxGeometry(100, 200, 50);
      var material1 = new THREE.MeshBasicMaterial({
        color: 0xffffff,
        wireframe: true,
      });
      var mesh1 = new THREE.Mesh(geometry, material1);
      mesh1.position.setY(100);

      var material2 = new THREE.MeshBasicMaterial({
        color: 0xff0000,
        wireframe: true,
      });
      var mesh2 = new THREE.Mesh(geometry, material2);
      mesh2.position.setY(100);

      // Entities
      entity1 = new SteeringEntity(1, mesh1);
      entity1.maxSpeed = 15;
      entity1.lookAtDirection = true;
      entity1.position.set(
        Math.random() * (5000 - -5000) + -5000,
        0,
        Math.random() * (5000 - -5000) + -5000
      );

      entity2 = new SteeringEntity(2, mesh2);
      entity2.maxSpeed = 10;
      entity2.lookAtDirection = true;
      entity2.position.set(
        Math.random() * (5000 - -5000) + -5000,
        0,
        Math.random() * (5000 - -5000) + -5000
      );

      scene.add(entity1);

      scene.add(entity2);

      //Plane boundaries (do not cross)
      boundaries = new THREE.Box3(
        new THREE.Vector3(-5000, 0, -5000),
        new THREE.Vector3(5000, 0, 5000)
      );

      params = { avoidCollisions: true };

      //Gui
      var gui = new dat.GUI();

      gui.add(params, "avoidCollisions").name("Avoid Collisions");
      var f1 = gui.addFolder("White Entity");
      f1.add(entity1, "maxSpeed", 1, 50).name("Max Speed").step(1);
      f1.add(entity1, "maxForce", 1, 20).name("Max Force").step(1);
      f1.add(entity1, "lookAtDirection").name("Look at Direction");
      f1.open();

      var f2 = gui.addFolder("Red Entity");
      f2.add(entity2, "maxSpeed", 1, 50).name("Max Speed").step(1);
      f2.add(entity2, "maxForce", 1, 20).name("Max Force").step(1);
      f2.add(entity2, "lookAtDirection").name("Look At Direction");
      f2.open();

      window.addEventListener("resize", onWindowResize, false);
      document.addEventListener("mousedown", onClick, true);
      animate();
    }

    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function animate() {
      requestAnimationFrame(animate);
      controls.update();

      //entity 1
      entity1.evade(entity2);
      if (params.avoidCollisions) entity1.avoid([entity2]);
      if (entity1.lookAtDirection) entity1.lookWhereGoing(true);
      else entity1.rotation.set(0, 0, 0);

      entity1.update();

      //entity 2
      entity2.pursue(entity1);
      if (params.avoidCollisions) entity2.avoid([entity1]);
      if (entity2.lookAtDirection) entity2.lookWhereGoing(true);
      else entity2.rotation.set(0, 0, 0);

      entity2.update();

      entity1.bounce(boundaries);
      entity2.bounce(boundaries);

      renderer.render(scene, camera);
      stats.update();
    }
  </script>

  <body onload="init('container')">
    <div id="container"></div>
    <div id="msg">
      <span style="color: #bfff00; font-weight: bold">EVADE:</span><br />Red
      pursues White.<br />White evade from RED.<br />ALT + Click on the floor to
      change White position
    </div>
    <a
      href="https://github.com/erosmarcon/three-steer/blob/master/examples/Evade.html"
      target="_blank"
      ><div class="view-source">View source</div></a
    >
  </body>
</html>
